package restructure;

import java.util.Enumeration;
import java.util.Vector;

/**
 * @Description
 * @Date 2021/9/19
 * @Created by Jonathan
 */
public class Example {
    private int _quantity;
    private int _itemPrice;

    private int _primaryForce;
    private int _secondaryForce;
    private int _mass;
    private int _delay;


    public void printOwing() {
        Vector<Object> vector = new Vector<>();
        Enumeration<Object> e = vector.elements();

    }

    /**
     * 原来的函数
     */
    double getPrice() {
        int basePrice = _quantity * _itemPrice;
        double discountFactor;
        if (basePrice > 1000) {
            discountFactor = 0.95;
        } else {
            discountFactor = 0.98;
        }
        return basePrice * discountFactor;
    }

    /**
     * 重构之后
     * 用final查看有几处被修改 有多处的话  编译器会发出警告
     * 【以查询取代临时变量】
     */
    double getPriceRe() {
        return basePrice() * discountFactor();
    }


    private double discountFactor() {
        if (basePrice() > 1000) return 0.95;
        else return 0.98;
    }

    // 这两种那个好一点呢???
    private double discountFactor1() {
        double result;
        if (basePrice() > 1000) {
            result = 0.95;
        } else {
            result = 0.98;
        }
        return result;
    }

    /*private int basePrice() {
        return _quantity * _itemPrice;
    }*/

    /**
     * 【引入解释性变量】
     * 从一个简单的计算开始
     */
    public double price() {
        return _itemPrice * _quantity
                - Math.max(0, _quantity - 500) * _itemPrice * 0.05
                + Math.min(_itemPrice * _quantity * 0.1, 100.0);
    }

    public double priceRe1() {
        final int basePrice = _itemPrice * _quantity;
        final double quantityDiscount = Math.max(0, _quantity - 500) * _itemPrice * 0.05;
        final double shipping = Math.min(basePrice * 0.1, 100.0);
        return basePrice - quantityDiscount + shipping;
    }

    /**
     * 同一对象的任何一部分都可以根据自己的需要提炼出这些函数
     *
     * @return
     */
    public double priceRe2() {
        return basePrice() - quantityDiscount() + shipping();
    }

    private double basePrice() {
        return _itemPrice * _quantity;
    }

    private double quantityDiscount() {
        return Math.max(0, _quantity - 500) * _itemPrice * 0.05;
    }

    private double shipping() {
        return Math.min(basePrice() * 0.1, 100.0);
    }

    /**
     * 分解临时变量 split temporary variable
     */

    public double getDistanceTravelled(int time) {
        double result;
        double acc = _primaryForce / _mass;
        int primaryTime = Math.min(time, _delay);
        result = 0.5 * acc * primaryTime * primaryTime;
        int secondaryTime = time - _delay;
        if (secondaryTime > 0) {
            double primaryVel = acc * _delay;
            acc = (_primaryForce + _secondaryForce) / _mass;
            result += primaryVel * secondaryTime + 0.5 * acc * secondaryTime * secondaryTime;
        }
        return result;
    }

    /**
     * 临时变量有很多用途：被多次赋值的有两种情况：1)循环变量 2)结果收集变量
     * 如果临时变量被赋值超过一次，就意味着承担多个责任
     * 如果承担多个责任，就应该被替换成多个临时变量，每个变量只承担一个责任
     * 同一个临时变量承担两件不同的事情，会令代码阅读者糊涂
     *
     * @param time
     * @return
     */
    public double getDistanceTravelledRe(int time) {
        double result;
        final double primaryAcc = _primaryForce / _mass;
        int primaryTime = Math.min(time, _delay);
        result = 0.5 * primaryAcc * primaryTime * primaryTime;
        int secondaryTime = time - _delay;
        if (secondaryTime > 0) {
            double primaryVel = primaryAcc * _delay;
            double secondaryAcc = (_primaryForce + _secondaryForce) / _mass;
            result += primaryVel * secondaryTime + 0.5 * secondaryAcc * secondaryTime * secondaryTime;
        }
        return result;
    }

    /**
     * 移除对参数的赋值
     * 重构之前
     */
    public int discount(int inputVal, int quantity, int yearToDate) {
        if (inputVal > 50) inputVal -= 2;
        if (quantity > 100) inputVal -= 1;
        if (yearToDate > 100) inputVal -= 4;
        return inputVal;
    }

    /**
     * @param inputVal
     * @param quantity
     * @param yearToDate
     * @return
     */
    public int discountRe(int inputVal, int quantity, int yearToDate) {
        int result = inputVal;
        if (inputVal > 50) result -= 2;
        if (quantity > 100) result -= 1;
        if (yearToDate > 100) result -= 4;
        return result;
    }

    /**
     * 加final修饰
     *
     * @param inputVal
     * @param quantity
     * @param yearToDate
     * @return
     */
    public int discountRe1(final int inputVal, final int quantity, final int yearToDate) {
        int result = inputVal;
        if (inputVal > 50) result -= 2;
        if (quantity > 100) result -= 1;
        if (yearToDate > 100) result -= 4;
        return result;
    }


}
